package com.aiyige.utils.httpcache;

import android.text.TextUtils;

import com.aiyige.base.api.ResponseCode;

import okhttp3.MediaType;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Created by zhuyakun on 2018/1/12.
 */

public class HttpCacheWrapper implements Callback<ResponseBody> {
    public static final String TAG = HttpCacheWrapper.class.getSimpleName();
    public static final long HTTP_CACHE_DURATION = 60 * 60 * 1000;
    boolean backRequest;
    boolean fromCache;
    boolean cacheResult;
    Call<ResponseBody> call;
    Callback<ResponseBody> callback;

    private HttpCacheWrapper(Builder builder) {
        backRequest = builder.backRequest;
        fromCache = builder.fromCache;
        cacheResult = builder.cacheResult;
        call = builder.call;
        callback = builder.callback;
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    public void enqueue() {
        if (fromCache) {
            String json = HttpCache.getInstance().get(call.request().url().toString());
            if (!TextUtils.isEmpty(json)) {
                Response<ResponseBody> response = Response.success(ResponseBody.create(MediaType.parse("text/plain"), json), new okhttp3.Response.Builder()
                        .code(ResponseCode.OK)
                        .message("OK")
                        .protocol(Protocol.HTTP_1_1)
                        .request(new Request.Builder().url(call.request().url().toString()).build())
                        .build());
                callback.onResponse(call, response);
            }
            if (TextUtils.isEmpty(json) || backRequest) {
                call.enqueue(this);
            }
        } else {
            call.enqueue(this);
        }
    }

    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        if (response.code() == ResponseCode.OK && cacheResult) {
            try {
                String json = response.body().string();
                HttpCache.getInstance().put(call.request().url().toString(), json, HTTP_CACHE_DURATION);
                callback.onResponse(call, Response.success(ResponseBody.create(MediaType.parse("text/plain"), json), new okhttp3.Response.Builder()
                        .code(ResponseCode.OK)
                        .message("OK")
                        .protocol(Protocol.HTTP_1_1)
                        .request(new Request.Builder().url(call.request().url().toString()).build())
                        .build()));
            } catch (Exception e) {
                callback.onFailure(call, e);
            }
        } else {
            callback.onResponse(call, response);
        }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        callback.onFailure(call, t);
    }


    public static final class Builder {
        private boolean backRequest;
        private boolean fromCache;
        private boolean cacheResult;
        private Call<ResponseBody> call;
        private Callback<ResponseBody> callback;

        private Builder() {
            backRequest = false;
            fromCache = false;
            cacheResult = false;
            call = null;
            callback = null;
        }

        public Builder backRequest(boolean backRequest) {
            this.backRequest = backRequest;
            return this;
        }

        public Builder fromCache(boolean fromCache) {
            this.fromCache = fromCache;
            return this;
        }

        public Builder cacheResult(boolean cacheResult) {
            this.cacheResult = cacheResult;
            return this;
        }

        public Builder call(Call<ResponseBody> call) {
            this.call = call;
            return this;
        }

        public Builder callback(Callback<ResponseBody> callback) {
            this.callback = callback;
            return this;
        }

        public HttpCacheWrapper build() {
            return new HttpCacheWrapper(this);
        }
    }
}
